package org.dromara.house.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.house.domain.bo.ParkContractBo;
import org.dromara.house.domain.dto.ParkDetailsDto;
import org.dromara.house.domain.entity.ParkContract;
import org.dromara.house.domain.entity.ParkContractCheckOut;
import org.dromara.house.domain.entity.ParkContractDetails;
import org.dromara.house.domain.entity.ParkTenant;
import org.dromara.house.mapper.ParkContractCheckOutMapper;
import org.dromara.house.mapper.ParkContractDetailsMapper;
import org.dromara.house.mapper.ParkContractMapper;
import org.dromara.house.mapper.ParkTenantMapper;
import org.dromara.house.service.ParkContractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 园区租赁合同表 服务实现类
 * </p>
 *
 * @author LCH
 * @since 2025-08-26
 */
@Service
public class ParkContractServiceImpl extends ServiceImpl<ParkContractMapper, ParkContract> implements ParkContractService {
    @Autowired
    private ParkContractDetailsMapper parkContractDetailsMapper;

    @Autowired
    private ParkContractCheckOutMapper parkContractCheckOutMapper;
    @Autowired
    private ParkTenantMapper parkTenantMapper;

    @Override
    public TableDataInfo<ParkContract> selectPageContractList(ParkContractBo bo, PageQuery pageQuery) {
        if (ObjectUtil.isNotEmpty(bo.getLeaseStatus())){
            Date date = new Date();
            Date date1 = get60DaysLater(date);
            if (bo.getLeaseStatus() == 1) {
                bo.setEndDate(date1);
            } else if (bo.getLeaseStatus() == 2) {
                bo.setStartDate(date);
                bo.setEndDate(date1);
            } else if (bo.getLeaseStatus() == 3) {
                bo.setEndDate(date);
            }
        }


        Page<ParkContract> page = baseMapper.selectPageContractList(bo, pageQuery.build());
        for (ParkContract contract : page.getRecords()) {
            //查询详情对象并且添加
//            List<ParkContractDetails> parkContractDetails = parkContractDetailsMapper.selectByParkContractId(contract.getId());
//            contract.setParkContractDetails(parkContractDetails);

            //获取租赁结束天数与今日进行比较，比今天小取赋值为0天，比今天大，算出离到期还有多少天
            String format = DateUtil.format(contract.getLeaseEnd(), "yyyy-MM-dd");
            int i = calculateRemainingDays(format);
            contract.setRemainingDays(i);

            //查询退租对象，返回
//            ParkContractCheckOut parkContractCheckOut = parkContractCheckOutMapper.selectByParkContractId(contract.getId());
//            contract.setParkContractCheckOut(parkContractCheckOut);
            Long outId = contract.getOutId();
            //校验租期状态，返回
            if (i > 60 && ObjectUtil.isEmpty(outId)) {
                contract.setLeaseStatus(1);
            }
            if (i >= 1 && i <= 60 && ObjectUtil.isEmpty(outId)) {
                contract.setLeaseStatus(2);
            }
            if (i <= 0 && ObjectUtil.isEmpty(outId)) {
                contract.setLeaseStatus(3);
            }
            if (ObjectUtil.isNotEmpty(outId)) {
                contract.setLeaseStatus(4);
            }

        }

        return TableDataInfo.build(page);
    }
    public Date get60DaysLater(Date date) {
        // 直接偏移 60 天（第一个参数为当前时间字符串，第二个为偏移天数）
        return DateUtil.offsetDay(date, 60);
    }
    /**
     * 计算租赁剩余天数（若已到期则返回0）
     *
     * @param leaseEndDate 租赁结束日期（格式：yyyy-MM-dd，如 2024-12-31）
     * @return 剩余天数（≥0）
     * @throws IllegalArgumentException 若输入日期格式无效
     */
    public static int calculateRemainingDays(String leaseEndDate) {

        // 2. 解析字符串为LocalDate（支持yyyy-MM-dd格式）
        LocalDate endDate;
        try {
            endDate = LocalDate.parse(leaseEndDate, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE);
        } catch (Exception e) {
            throw new IllegalArgumentException("日期格式错误，需为yyyy-MM-dd", e);
        }

        // 3. 获取今日日期（系统默认时区）
        LocalDate today = LocalDate.now();

        // 4. 计算天数差（endDate - today）
        long daysDifference = ChronoUnit.DAYS.between(today, endDate);

        // 5. 修正结果：若已到期或今日到期，返回0；否则返回剩余天数
        return (int) Math.max(daysDifference, 0);
    }

    @Override
    public ParkContract selectById(Long id) {
        ParkContract parkContract = baseMapper.selectById(id);
        //查询企业对象添加
        ParkTenant parkTenant = parkTenantMapper.selectById(parkContract.getTenantCode());
        parkContract.setParkTenant(parkTenant);
        //查询详情对象并且添加
        List<ParkContractDetails> parkContractDetails = parkContractDetailsMapper.selectByParkContractId(id);
        parkContract.setParkContractDetails(parkContractDetails);
        //查询退租对象，返回
        ParkContractCheckOut parkContractCheckOut = parkContractCheckOutMapper.selectByParkContractId(id);
        parkContract.setParkContractCheckOut(parkContractCheckOut);
        return parkContract;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> insertContract(ParkContract parkContract) {
        Date date = new Date();
        LoginUser loginUser = LoginHelper.getLoginUser();
        parkContract.setCreateTime(date);
        parkContract.setCreateBy(loginUser.getUserId());
        parkContract.setDeleteStatus(0);
        List<ParkContractDetails> parkContractDetails = parkContract.getParkContractDetails();
        int insert = baseMapper.insert(parkContract);
        //添加详情对象
        for (ParkContractDetails parkContractDetail : parkContractDetails) {
            //查询当前房间是否有未到期的租赁记录,有租赁记录并且没有退租，报错返回
            List<ParkDetailsDto> list = parkContractDetailsMapper.selectLeaseRecord(date, parkContractDetail.getHouseId(), null);
            for (ParkDetailsDto parkDetailsDto : list) {
                if (ObjectUtil.isNotEmpty(parkDetailsDto.getDetailsId()) && ObjectUtil.isEmpty(parkDetailsDto.getOutId())) {
                    return R.fail("楼宇：[" + parkContractDetail.getHousingName() + "]  房间：[" + parkContractDetail.getHouseName() + "] 有未到期的租赁记录");
                }
            }
            parkContractDetail.setId(null);
            parkContractDetail.setContractId(parkContract.getId());
            parkContractDetailsMapper.insert(parkContractDetail);
        }
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> updateContract(ParkContract parkContract) {
        Date date = new Date();
        LoginUser loginUser = LoginHelper.getLoginUser();
        parkContract.setUpdateTime(date);
        parkContract.setUpdateBy(loginUser.getUserId());
        for (ParkContractDetails parkContractDetail : parkContract.getParkContractDetails()) {
            //查询当前房间是否有未到期的租赁记录,有租赁记录并且没有退租，报错返回
            List<ParkDetailsDto> list = parkContractDetailsMapper.selectLeaseRecord(date, parkContractDetail.getHouseId(), parkContract.getId());
            for (ParkDetailsDto parkDetailsDto : list) {
                if (ObjectUtil.isNotEmpty(parkDetailsDto.getDetailsId()) && ObjectUtil.isEmpty(parkDetailsDto.getOutId())) {
                    return R.fail("楼宇：[" + parkContractDetail.getHousingName() + "]  房间：[" + parkContractDetail.getHouseName() + "] 有未到期的租赁记录");
                }
            }
        }


        //删除详情后重新添加
        LambdaQueryWrapper<ParkContractDetails> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParkContractDetails::getContractId, parkContract.getId());
        parkContractDetailsMapper.delete(queryWrapper);
        //添加详情对象
        for (ParkContractDetails parkContractDetail : parkContract.getParkContractDetails()) {
            parkContractDetail.setId(null);
            parkContractDetail.setContractId(parkContract.getId());
            parkContractDetailsMapper.insert(parkContractDetail);
        }
        baseMapper.updateById(parkContract);
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Long[] ids) {
        for (Long id : ids) {
            ParkContract parkContract = baseMapper.selectById(id);
            parkContract.setDeleteStatus(1);
            baseMapper.updateById(parkContract);
        }
        return 1;
    }

    @Override
    public int checkOut(ParkContractCheckOut parkContractCheckOut) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        parkContractCheckOut.setCreateTime(new Date());
        parkContractCheckOut.setCreateBy(loginUser.getUserId());
        return parkContractCheckOutMapper.insert(parkContractCheckOut);
    }

    private Wrapper<ParkContract> buildQueryWrapper(ParkContractBo bo) {
        LambdaQueryWrapper<ParkContract> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ObjectUtil.isNotEmpty(bo.getTenantCode()), ParkContract::getTenantCode, bo.getTenantCode());
        wrapper.eq(ParkContract::getDeleteStatus, 0);
        wrapper.orderByDesc(ParkContract::getCreateTime);
        return wrapper;
    }
}
